<template>
  <div class="rk-form-render-container">
    <v-form-render
      ref="formRenderRef"
      :form-json="formJson"
      :form-data="renderFormData"
      :enumsDataConfig="{
        dataPools: EnumsDataPools
      }"
      @formChange="renderFormChange"
      @loadedFormJson="renderFormJsonLoaded"
    >
      <template v-for="item in slotJson" #[item.value]>
        <component
          v-if="RkFormSlotModules.names.includes(item.value)"
          busiId="preview"
          :is="item.value"
          :ref="item.value"
          :formData="renderFormData"
          @setFormItemValue="setFormItemValue"
        >
        </component>
      </template>
    </v-form-render>
  </div>
</template>

<script>
import XEUtils from 'xe-utils'
import RkFormSlotModules from '@/components/form-slots/index.js'
import { EnumsDataPools } from '@/enums/enums-index.js'


export default {
  name: 'FormRenderPanel',
  components: {
    ...RkFormSlotModules.values
  },
  props: {
    formJson: { type: [Object, String], default: '' },
    slotJson: { type: [Array] },
    formData: { type: [Object], default: () => {
      return {}
    } }
  },
  provide () {
    return {
      getRenderFormData: () => {
        return this.renderFormData
      }
    }
  },
  watch: {
    formJson: {
      deep: true,
      immediate: true,
      handler(newValue, oldValue) {
        if (!XEUtils.isEmpty(newValue)) {
          const { formRenderRef } = this.$refs
          if (formRenderRef) {
            formRenderRef.setFormJson(newValue)
          }
        }
      },
    }
  },
  data () {
    return {
      EnumsDataPools,
      RkFormSlotModules,
      renderFormData: this.formData
    }
  },
  mounted() {
  },
  methods: {
    /**
     * 表单数据变更触发
     * @param {String} fieldName 修改字段名称
     * @param {Any} newValue 字段修改后的内容
     * @param {Any} oldValue 字段修改前的内容
     * @param {Object} formModel 表单数据
     */
    renderFormChange(fieldName, newValue, oldValue, formModel) {
      const { renderFormData, $refs: { formRenderRef } } = this
      if (formRenderRef) {
        this.renderFormData = { ...renderFormData, ...formModel }
      }
    },
    /**
     * 表单渲染组件，渲染完成后触发
     */
    renderFormJsonLoaded() {
      this.$emit('loadedFormJson')
    },
    /**
     * 设置单个表单字段的值
     *
     * @param {String} fieldName 表单字段名称
     * @param {String} fieldValue 表单字段内容
     */
    setFormItemValue(fieldName, fieldValue) {
      const { $refs: { formRenderRef } } = this
      formRenderRef.setFieldValue(fieldName, fieldValue)
    },
    /**
     * 获取渲染表单数据
     */
    getRenderFormData() {
      return new Promise(reslove => {
        const { renderFormData, slotJson, $refs } = this
        const { formRenderRef } = $refs
        const filedWidgets = formRenderRef.getFieldWidgets()
        const dataObj = {}
        const dataArray = filedWidgets.filter(item => item.type !== 'slot').map(item => {
          const itemObj = {
            guid: item.id,
            code: item.name,
            type: item.type,
            label: item.label,
            value: renderFormData[item.name] || '',
            dataField: item.dataField,
          }
          // 如果是开关组件，就将【true|false】转换为【1|0】
          if (item.type === 'switch') {
            itemObj.value = itemObj.value ? 1 : 0
          }
          dataObj[item.name] = itemObj
          return itemObj
        })
        // 封装插槽数据信息
        let slotsData = {}
        // 遍历插槽
        slotJson.forEach(item => {
          const { getCompData } = $refs[item.value]
          // 如果获取组件信息的方法不存在，跳过
          if (!getCompData) { return false }
          const compData = $refs[item.value].getCompData()
          slotsData = { ...slotsData, ...compData }
        })
        reslove({
          slotsData, dataArray, dataObj
        })
      })
    },
  }
}
</script>

<style lang="scss" scoped>
.rk-form-render-container {
  height: 100%;
  :deep(.render-form),
  :deep(.tab-container),
  :deep(.el-tabs),
  :deep(.el-tab-pane) {
    height: 100%;
  }
  :deep(.render-form > .container-wrapper) {
    &:first-child {
      height: 100%;
    }
  }
  :deep(.el-tabs) {
    display: flex;
    flex-direction: column;
  }
  :deep(.el-tabs__header) {
    background-color: #e3f1fe;
    margin-bottom: 0;
  }
  :deep(.el-tabs__nav-scroll) {
    padding: 0 5px;
  }
  :deep(.el-tabs__content) {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 0;
    padding-top: 15px;
  }
  :deep(.el-tab-pane) {
    .upload-main{
      padding: 0;
      position: relative;
      top: -15px;
    }
    // 处理插槽样式
    .slot-widget-item {
      flex: 1;
      min-height: 300px;
      .static-content-item,
      .slot-wrapper-render {
        height: 100%;
      }
    }
  }
}
</style>
